相信所有的程式開發人員一定都有聽過AOP,AOP
全名為Aspect-Oriented Programming
,單從字面上較無法理解這技術是用來做什麼的,用最簡單方式來說,就是將一些相同行為的流程獨立撰寫,應用在程式的橫切面,而其中最常見的就是每支程式的進入點跟結束點。
在這邊舉個簡單的例子,當用戶登入時我們需要紀錄Log以便後續維運確認資料,而當用戶修改資料時我們也需紀錄Log以便後續維運確認資料,在這種情形下,我們需要分別在每支程式上撰寫相關Log機制來記錄相關資訊,若有N支程式則需撰寫N次類似的程式碼,此時若我們將紀錄Log資訊的程式獨立出來,並固定在程式的進入點觸發,這樣的行為在AOP的術語中被稱為Cross-cutting concerns
,而AOP就是將這些Cross-cutting concerns收集起來,設計各個獨立可重複使用的物件,這些物件被稱之為Aspect
。
而今天我們要介紹專案中的麵包屑AOP的應用,有人這時可能會有疑問?麵包屑為什麼要透過AOP來產生,之所以會有這個機制,是因Sidebar會根據不同的帳號權限長出不一樣的功能選項,而PM希望麵包屑除了與Sidebar的階層一致外,還需根據不同的帳號權限有不一樣的麵包屑階層
基於以上需求,單一頁面要根據不同權限產出不同階層麵包屑,因此透過AOP機制固定在程式的進入點觸發,判斷目前是哪支程式在執行並讀取帳號權限,進而動態產出各頁面不同的麵包屑階層與內容。
for(int i=1; i<=Integer.valueOf(annotation.level()); i++) {
int index = i-1;
if(Const.AUTHORIZATION_STORE.equals(roleId)) {
breadcrumbName
= StringUtil.replaceByVarset(annotation.storeName()[index], model);
breadcrumbUrl
= StringUtil.replaceByVarset(annotation.storeUrl()[index], model);
} else {
breadcrumbName
= StringUtil.replaceByVarset(annotation.manageName()[index], model);
breadcrumbUrl
= StringUtil.replaceByVarset(annotation.manageUrl()[index], model);
}
if(StringUtils.isNotBlank(breadcrumbName)) {
request.getSession()
.setAttribute("breadcrumb_level" + i + "_name", breadcrumbName);
}
if(StringUtils.isNotBlank(breadcrumbUrl)) {
request.getSession()
.setAttribute("breadcrumb_level" + i + "_url", breadcrumbUrl);
}
}